package com.Reader;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.Atom;
import com.Exception.NotReadException;

/**
 * ReaderDB permet de recuperer des atomes à partir d'un fichier texte (.db)
 * @author florent
 * @see Reader
 */
public class ReaderDB extends Reader{

	private File[] fichiers; //noms des fichiers à lire
	
	Pattern pattern_comment = Pattern.compile("[//].*"); 				//expression régulière permettant de reconnaitre un commentaire
	Pattern pattern_atome = Pattern.compile("^([!]*)(.*)[(](.*)[)]$");  
	//expression régulière permettant de reconnaire un atome, et de récupérer son nom :1er (.*) et ses arguments : 2ème (.*)

	/**
	 * Constuit un ReaderDB sur plusieurs fichier
	 * @param fichiers nom des fichiers
	 */
	public ReaderDB(File[] fichiers){
		this.fichiers = fichiers;
	}

	/**
	 * Récupère un atome à partir d'une ligne du fichier
	 * @param line ligne du fichier (à analyser) contenant l'atome
	 * @return l'atome généré
	 * @throws NotReadException
	 */
	private Atom getAtome(String line) throws NotReadException{
		Atom atome = null; //atome vide

		int pos = 1;

		Matcher matcher_comment = pattern_comment.matcher(line); //teste la présence des commentaire

		if(!matcher_comment.find()){ //si ce n'est pas commenté
			
			Matcher matcher_info = pattern_atome.matcher(line); //teste si on a un atome

			if(matcher_info.matches()){ //si on a un atome

				//récupère son nom/prédicat
				String gr1 = matcher_info.group(pos);
				
				boolean truth = true;
				
				if(gr1.equals("!"))
					truth = false;
				
				//vérifie si il est vrai/faux
				
				atome = new Atom(matcher_info.group(++pos),truth); //group(1) = predicat

				//puis lui ajoute ses constantes
				for(String constante : matcher_info.group(++pos).split(",")){ //découpe les constantes
					atome.addConstante(constante);
				}
			}
			else
				throw new NotReadException("pas un atome");
		}
		else
			throw new NotReadException("commenté");

		return atome;
	}

	/**
	 * Ouvre un fichier avec son nom (pour les fichiers multiples)
	 * @param fichier nom du fichier à ouvrir
	 */
	private void open(File fichier){
		try {
			file = new BufferedReader(new FileReader(fichier)); //change le bufferedReader, pointe sur le nouveau file
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Récupère tout les atomes contenus dans tout les fichiers
	 * Et créé le liens entre ces atomes et 
	 * @return la liste des atomes lu
	 */
	public ArrayList<Atom> getAtomes(){

		ArrayList<Atom> atomes = new ArrayList<Atom>(); //créé une liste vide d'atomes

		for(File fichier : fichiers){ //ouvre chaque fichier
			open(fichier);

			String line;
			try {
				while((line = file.readLine()) != null){
					try{
						Atom atome = getAtome(line);
						atomes.add(atome);
					}catch(NotReadException n){
						//pas un atome
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			} 

			close();
		}

		return atomes;
	}
}
